/**********************************************************************************************/
/* FBL_Value_String.h 	                                                   					  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#ifndef _FBL_Value_String_h 
	#define _FBL_Value_String_h
#pragma once

// FBL:
#include <VShared/FBL/publ/Interfaces/FBL_I_Localizable.h>
#include <VShared/FBL/publ/Interfaces/FBL_I_Serializable.h>
#include <VShared/FBL/publ/Interfaces/FBL_I_Value.h>
#include <VShared/FBL/publ/Util_classes/FBL_StringConversion.h>
#include <VShared/FBL/publ/Values/FBL_type_traits.h>
#include <VShared/FBL/publ/Values/FBL_Type2String.h>

// FINAL:
#include <VShared/FBL/publ/Headers/FBL_pre_header.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
/** if we do Value_String( NULL ) we get ambiguity between 1 and 2 form of ctors.
	To fix this we need Value_String( (char*) NULL ).
	To make things looks better we provide here pointer on NULL string that can be used as
	Value_String( pNullStr ).
*/
extern const UChar* pNullStr;


/**********************************************************************************************/
/**	This is pointer to "" string.
	Why? Just for completness. :-). We have for all types (if its possible) default value.
	For example for String class the static member String.Empty - represent empty string value.
*/
extern const UChar* pEmptyStr;


/**********************************************************************************************/
template<class T> 
void Convert_Str_To_Type( const UChar* inValue, T* outValue )
{
	type_traits<T>::from_str( inValue, outValue );
}


/**********************************************************************************************/
template<class T> 
char* Convert_Type_To_Str( T* inValue, UChar* outValue )  
{
	return (char*)type_traits<T>::to_str( inValue, outValue );
}


/**********************************************************************************************/
#pragma mark class Value_string
//
class FBL_SHARED_EXP_CLASS Value_string : 
	public I_Value, 
	public I_Serializable
{
		IMPLEMENT_UNKNOWN(Value_string)											
		BEGIN_INTERFACE_TABLE(Value_string)										
			IMPLEMENT_INTERFACE(I_Value)										
			IMPLEMENT_INTERFACE(I_Serializable)										
		END_INTERFACE_TABLE()

	public://///////////////////////////////////////////////////////////////////////////////////

		typedef	Value_string									this_type;

		typedef       smart_ptr<this_type>						pointer;
		typedef const pointer									const_pointer;
		typedef       this_type&								reference;
		typedef const this_type&								const_reference;


	public://///////////////////////////////////////////////////////////////////////////////////

	// Construction:

							Value_string( void );

							/**	This ctor allow create empty Value_string with buffer for 
								the specified number of characters. 
								@param inChars	- count of character for allocating buffer.*/
							Value_string( 
								tslen 				inChars,
								I_Localizable_Ptr 	inLocalizable = NULL );

							/**	This is a copy-ctor. 
								@param inOther - other Value_string.*/
							Value_string( 
								const_reference 	inOther );

virtual						~Value_string( void );
							

	public://///////////////////////////////////////////////////////////////////////////////////

// interface I_Value:

virtual	I_Value_Ptr			Clone( bool inCopyData = true ) const throw();

							
	// ---------------------
	// Properties:
	
virtual ulong 				get_Allocated( void ) const throw();
virtual bool 				put_Allocated( ulong inByteSize ) throw();
								
virtual ulong 				get_ByteLength( void ) const throw();
virtual void 				put_ByteLength( ulong inNewLength );

virtual	ulong				get_ByteLengthForIndex( void ) const throw();	
							
virtual VALUE_CATEGORY		get_Category( void ) const  throw();

virtual bool				get_IsNullable( void ) const throw() { return false; }
virtual bool 				get_IsNull( void ) const throw();
virtual void 				put_IsNull( bool inValue ) throw();

virtual bool				get_IsRemote( void ) const throw() { return mIsRemote; }
virtual void 				put_IsRemote( bool inValue ) throw() { mIsRemote = inValue; }

virtual ulong 				get_Length( void ) const throw();

virtual ulong				get_MaxChars( void ) const throw();

virtual ulong				get_StorageSize( void ) const throw(); 

virtual VALUE_TYPE			get_Type( void ) const  throw();

virtual String				get_TypeString( const char inLocale[] = "en_US" ) const throw()
								{ return TypeCode2String(kTypeString, inLocale); }

	// ---------------------
	// Value access:

virtual const char*			begin( void ) const throw();
virtual const char*			end	 ( void ) const throw();

virtual	void				Assign( const I_Value& inValue ) throw();

virtual void 				CopyToIndex( void* outBuffer, bool inSwapBytes ) const throw();
virtual void 				CopyFromIndex( const void* inBuffer, bool inSwapBytes ) throw();


	// ---------------------
	// Value compare methods:

virtual	int					Compare( 
								const I_Value& 	inOther,
								COMPARE_TYPE 	inCompareType = kNatureCompare ) const throw();

virtual	int					CompareIndexValues( 
								const void* inLeft,
								const void* inRight,
								bool		inSwapBytes ) const throw();

virtual	int					CompareToIndexValue( 
								Const_I_Value_Ptr 	inTestValue,
								const void* 		inIndexValue,
								ulong				inParam,
								bool				inSwapBytes ) const throw();


	// ---------------------
	// to/from string:

virtual	String				get_String( tslen inLimit = -1 ) const;
virtual void				put_String( const String& inStr );

virtual UChar*				get_String( 
								UChar* outString, 
								tslen inBufferChars = -1 ) const;

virtual void				put_String( 
								const UChar* inBegin, 
								const UChar* inEnd = NULL );

	// ---------------------

virtual char*				get_String( 
								char* outString, 
								tslen inBufferChars = -1 ) const;

virtual void				put_String( 
								const char* inBegin, 
								const char* inEnd = NULL );


	// ---------------------
	// Numeric properties:

virtual bool				get_Boolean( void ) const;
virtual uchar				get_Byte( void ) const;
virtual short				get_Short( void ) const;
virtual ushort				get_UShort( void ) const;
virtual long				get_Medium( void ) const;
virtual long				get_Long( void ) const;
virtual ulong				get_ULong( void ) const;
virtual llong				get_LLong( void ) const;
virtual ullong				get_ULLong( void ) const;
virtual float				get_Float( void ) const;
virtual double				get_Double( void ) const;

virtual void				put_Boolean( bool inValue );
virtual void				put_Byte( uchar inValue );
virtual void				put_Short( short inValue );
virtual void				put_UShort( ushort inValue );
virtual void				put_Medium( long inValue );
virtual void				put_Long( long inValue );
virtual void				put_ULong( ulong inValue );
virtual void				put_LLong( llong inValue );
virtual void				put_ULLong( ullong inValue );
virtual void				put_Float( float inValue );
virtual void				put_Double( double inValue );


	// ---------------------
	// Byte swapping:

virtual void				SwapBytes( void ) 							 { }
virtual void				SwapBytes( void* inValue ) const 			 { argused1(inValue); }							
virtual void				SwapBytes( const void* inSrc, void* inDest ) { argused2(inSrc, inDest); }


	public://///////////////////////////////////////////////////////////////////////////////////
 
// interface I_Serializable:

virtual void				From( I_IStream_Ptr inStream, bool inBlock = true );
virtual void				From( I_PacketRcv* 	inPacket, bool inBlock = true );

virtual void				To( I_OStream_Ptr inStream, bool inBlock = true ) const;
virtual void				To( I_PacketSnd*  inPacket, bool inBlock = true ) const;


	
	public://///////////////////////////////////////////////////////////////////////////////////
 
// THIS CLASS API:

		// <Localizable> [r/o]

		I_Localizable*		get_Localizable( void ) const throw() 
								{ return mpLocalizable; } 		
								
		void				put_Localizable( I_Localizable* inLocalzable ) throw() 
								{ mpLocalizable = inLocalzable; } 		

		// <IsSingleByte>
		bool				get_IsSingleByte( void ) const throw() { return mIsSingleByte; } 
		void				put_IsSingleByte( bool inValue ) throw() { mIsSingleByte = inValue; } 


							/** Find the END ZERO byte in Value. 
								We need this after READ from a disk file for a FIXED SIZE type. */
		void				LocateEnd( void );
		

	public://///////////////////////////////////////////////////////////////////////////////////

// ---------------------
// THIS CLASS additional forms when we pass converter:
	
virtual void 				DoAssignFromUTF16( 
								const Value_string* inValue,
								I_Converter* 		inConverter ) throw();
 
virtual char*				get_String( 
								char* 				outString, 
								tslen 				inBufferChars,
								I_Converter* 		inConverter ) const;

virtual void				put_String( 
								const char* 		inBegin, 
								const char* 		inEnd,
								I_Converter* 		inConverter );


	protected:////////////////////////////////////////////////////////////////////////////////// 

// THIS CLASS API:

							// Allocate buffer that can keep inBytes including end-zero.
		void 				Allocate( ulong inBytes );
	
							/**	Assigns the specified string into this value. 
								Truncates the given string if needed .
								@param inStart	- begin of string buffer.
								@param inEnd	- end of string buffer.
								@return a pointer on the start of our string value.
								In the case inStart == NULL, we consider this as NULL 
								value assigment. */
		const UChar*		Assign( 
								const UChar* inStart, 
								const UChar* inEnd = NULL ) throw();

		void				DoAssign( 
								const UChar* inStart, 
								const UChar* inEnd = NULL) throw();

		void				DoAssign( 
								const I_Value& inValue ) throw();

		void				SetupConversionFlag( void );


							// Receiving value from server.
		void				From_OnClientSide( I_PacketRcv* inPacket );

							// Receiving value from client.
		void				From_OnServerSide( I_PacketRcv* inPacket );
							// Helper for From_OnServer_Side.
		void				From_OnServerSide_U( I_PacketRcv* inPacket, ulong inByteLength );


							// Sending value to the server.
		void				To_OnClientSide( I_PacketSnd* inPacket ) const;

							// Sending value to the client.
		void				To_OnServerSide( I_PacketSnd* inPacket ) const;
							// Helper for To_OnServerSide.
		void				To_OnServerSide_U( I_PacketSnd* inPacket, ulong inByteLength ) const;


	protected://////////////////////////////////////////////////////////////////////////////////

	/// --- Data members ---
	
		UChar*				m_pStartU;		///< Start of buffer.
		UChar*				m_pBufferEndU;	///< End of buffer.
		UChar*				m_pEndU;		///< End of the value. 

	protected://////////////////////////////////////////////////////////////////////////////////

		I_Localizable*		mpLocalizable;

		bool				mIsRemote; 		// implements <IsRemote> property.

		bool				mIsSingleByte;	// TRUE if this value keep single byte string.
		bool				mNeedConvertToStorageEncoding;


	public://///////////////////////////////////////////////////////////////////////////////////

// Section of class with TEST - helper methods.
// for internal use.
 
#if FBL_TEST_CODE

							/**	This ctors allows init Value by some string.
								Actually this form will be used only in tests. 
								@param inStart	- begin of initialization string.
								@param inEnd	- end of initialization string. */
							Value_string( 
								const UChar* inStart, 
								const UChar* inEnd = NULL );
							
							Value_string(
								const char* inStart, 
								const char* inEnd = NULL );

							Value_string( tslen inChars, int dummy );

#endif // FBL_TEST_CODE

virtual void				Init( void ) throw();
virtual void 				Increment( void ) throw();

//#endif // FBL_TEST_CODE
							
};


/**********************************************************************************************/
///
#pragma mark class Value_string_null

class FBL_SHARED_EXP_CLASS Value_string_null : public Value_string
{
	public://///////////////////////////////////////////////////////////////////////////////////

		typedef	Value_string_null								this_type;

		typedef       smart_ptr<this_type>						pointer;
		typedef const pointer									const_pointer;
		typedef       this_type&								reference;
		typedef const this_type&								const_reference;


	public://///////////////////////////////////////////////////////////////////////////////////

	// --- Construction ---

							Value_string_null( void ) throw();

							/**	This ctor allow create empty value_String with buffer of for 
								specified count of character. 
								@param inChars	- count of character for allocating buffer.*/
							Value_string_null( 
								tslen inChars,
								I_Localizable_Ptr inLocalizable = NULL ) throw();

							/**	This is are copy-ctor. 
								@param inOther - other Value_string.*/
							Value_string_null( const_reference inOther ) throw();

virtual						~Value_string_null( void );
							

	public://///////////////////////////////////////////////////////////////////////////////////

// interface I_Value:

virtual	I_Value_Ptr			Clone( bool inCopyData = true ) const throw() ;

	// ---------------------
	// Properties:

virtual bool				get_IsNullable( void ) const throw() { return true; }	
virtual bool 				get_IsNull( void ) const throw();
virtual void 				put_IsNull( bool inValue ) throw();

	// ---------------------
	// Numeric properties:

virtual void				put_Boolean( bool inValue );
virtual void				put_Byte( uchar inValue );
virtual void				put_Short( short inValue );
virtual void				put_UShort( ushort inValue );
virtual void				put_Medium( long inValue );
virtual void				put_Long( long inValue );
virtual void				put_ULong( ulong inValue );
virtual void				put_LLong( llong inValue );
virtual void				put_ULLong( ullong inValue );
virtual void				put_Float( float inValue );
virtual void				put_Double( double inValue );

	// ---------------------
	// Value access:

virtual	int					Compare( 
								const I_Value& 	inOther,
								COMPARE_TYPE 	inCompareType = kNatureCompare ) const throw();


	protected://////////////////////////////////////////////////////////////////////////////////

		bool				mIsNull;		///< nullable flag.


	public://///////////////////////////////////////////////////////////////////////////////////

// Section of class with TEST - helper methods.
// for internal use.
 
#if FBL_TEST_CODE
							/**	This ctors allows init Value by some string.
								Actually this form will be used only in tests. 
								@param inStart	- begin of initialization string.
								@param inEnd	- end of initialization string. */
							Value_string_null( 
								const UChar* inStart, 
								const UChar* inEnd = NULL ) throw();

							Value_string_null(
								const char* inStart, 
								const char* inEnd  = NULL) throw();

#endif // FBL_TEST_CODE

};


/**********************************************************************************************/
typedef Value_string Value_varchar;
typedef Value_string_null Value_varchar_null;


/**********************************************************************************************/
FBL_SMART_PTR( Value_string );
FBL_SMART_PTR( Value_varchar );
FBL_SMART_PTR( Value_string_null );
FBL_SMART_PTR( Value_varchar_null );


/**********************************************************************************************/
FBL_End_Namespace

#include <VShared/FBL/publ/Headers/FBL_post_header.h>

#endif // _FBL_Value_String_h
